package org.jiuling.network.tools.request.http.base;

import org.jiuling.local.tools.verify.MapVerify;
import org.jiuling.local.tools.verify.ObjectVerify;
import org.jiuling.network.tools.request.http.config.HttpRequestDataConfig;
import org.jiuling.network.tools.request.http.enums.RequestMethodEnum;
import org.jiuling.network.tools.request.http.exception.HttpRequestRuntimeException;
import org.jiuling.network.tools.request.http.model.HttpRequestBody;
import org.jiuling.network.tools.request.http.model.HttpRequestHeader;
import org.jiuling.network.tools.request.http.model.HttpRequestParam;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.nio.charset.StandardCharsets;

/**
 * Http请求核心
 * @author 紫灵
 * @date 2024年02月20日 01时34分28秒
 */
public abstract class HttpRequestBase {

    /** 请求地址 */
    private final String path;
    /** Http请求数据配置 */
    protected HttpRequestDataConfig httpRequestDataConfig;

    public HttpRequestBase(String path) {
        this.path = path;
        this.httpRequestDataConfig = new HttpRequestDataConfig();
    }

    public HttpRequestDataConfig.Builder openHttpRequestDataConfigBuilder(){
        return this.httpRequestDataConfig.builder();
    }

    /**
     * 获取URL链接
     * @return URL链接
     * @throws IOException IO异常
     */
    protected URLConnection getURLConnection() throws IOException {
        Proxy proxy = httpRequestDataConfig.getProxy();
        // 开启远程连接
        return ObjectVerify.isNull(proxy) ? getUrl().openConnection() :  getUrl().openConnection(proxy);
    }

    /**
     * 获取URL
     * @return URL
     * @throws MalformedURLException URL格式异常
     */
    private URL getUrl() throws MalformedURLException {
        StringBuffer urlStringBuffer = new StringBuffer(path);
        HttpRequestParam httpRequestParam = httpRequestDataConfig.getHttpRequestParam();
        if(!MapVerify.isNull(httpRequestParam)){
            urlStringBuffer.append("?");
            httpRequestParam.forEach((k,v)->{
                try {
                    urlStringBuffer.append(k).append("=").append(URLEncoder.encode(String.valueOf(v), "utf-8")).append("&");
                }
                //不支持的编码异常
                catch (UnsupportedEncodingException e) {
                    throw new HttpRequestRuntimeException(e);
                }
            });
            urlStringBuffer.deleteCharAt(urlStringBuffer.length()-1);
        }
        return new URL(urlStringBuffer.toString());
    }

    /**
     * 链接
     * @param urlConnection URL链接
     * @return URL链接
     */
    protected URLConnection connect(URLConnection urlConnection) throws IOException {
        // 设置连接超时时间
        urlConnection.setConnectTimeout(httpRequestDataConfig.getConnectTimeout());
        // 设置读取超时时间
        urlConnection.setReadTimeout(httpRequestDataConfig.getReadTimeout());

        HttpRequestHeader httpRequestHeader = httpRequestDataConfig.getHttpRequestHeader();
        // 设置请求头
        if(!MapVerify.isNull(httpRequestHeader)){
            httpRequestHeader.forEach((k,v) ->{
                urlConnection.setRequestProperty(k,String.valueOf(v));
            });
        }

        HttpRequestBody httpRequestBody = httpRequestDataConfig.getHttpRequestBody();
        // 设置请求内容
        if(!RequestMethodEnum.GET.equals(httpRequestDataConfig.getRequestMethod()) &&
                !ObjectVerify.isNull(httpRequestBody)){
            // 设置输入实处权限
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);
            OutputStream outputStream = urlConnection.getOutputStream();
            outputStream.write(httpRequestBody.getBody().getBytes(StandardCharsets.UTF_8));
            // 关闭输入流
            outputStream.close();
        }else {
            // 获取连接
            urlConnection.connect();
        }
        return urlConnection;
    }
}
